#!/usr/bin/python3
# coding:utf-8
#
# @Time    : 2024/11/14 20:44
# @Email   : 1105293248@qq.com
# @File    : browser.py
# @IDE     : PyCharm
import os
import sys
import time

from DrissionPage import Chromium
from DrissionPage import ChromiumOptions
from loguru import logger


def get_browser_path(browser_name):
    if sys.platform == "win32":
        try:
            import winreg
            key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,
                                 r"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\\" + browser_name)
            path, _ = winreg.QueryValueEx(key, "")
            return path
        except FileNotFoundError:
            return None
    elif sys.platform == "darwin":
        # For macOS, we assume Chrome is installed in /Applications directory
        possible_paths = [
            "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",  # Standard Chrome installation
            "/Applications/Chromium.app/Contents/MacOS/Chromium",  # Chromium browser path
        ]
        for path in possible_paths:
            if os.path.exists(path):
                return path
        return None
    else:
        # If it's neither Windows nor macOS, return None
        return None


def find_chrome_path():
    return get_browser_path("chrome.exe")


def find_edge_path():
    return get_browser_path("msedge.exe")


class Browser:
    _instance = None
    _browsers = {}  # 存储多个浏览器实例
    _port = 9223  # 初始端口号

    def __init__(self, chrome_path=None, edge_path=None, multi_browser_mode=False):
        self.chrome_path = chrome_path or find_chrome_path()
        self.edge_path = edge_path or find_edge_path()
        self.multi_browser_mode = multi_browser_mode
        logger.debug(f"Chrome 路径: {self.chrome_path}")
        logger.debug(f"Edge 路径: {self.edge_path}")
        logger.debug(f"多浏览器模式: {self.multi_browser_mode}")
        self.browser = None

    @classmethod
    def get_instance(cls, multi_browser_mode=False):
        """
        获取Browser实例（单例模式）
        """
        if not cls._instance:
            cls._instance = Browser(multi_browser_mode=multi_browser_mode)
        return cls._instance

    def _get_next_port(self):
        """
        获取下一个可用端口
        """
        Browser._port += 1
        return Browser._port

    def latest_tab(self, browser_id=None):
        """
        获取最新标签页
        :param browser_id: 浏览器ID，用于多浏览器模式
        """
        try:
            if self.multi_browser_mode:
                if browser_id not in self._browsers:
                    self.init_browser(browser_id)
                return self._browsers[browser_id].latest_tab
            else:
                if not self.browser or not self.browser.latest_tab:
                    self.init_browser()
                return self.browser.latest_tab
        except:
            self.init_browser(browser_id if self.multi_browser_mode else None)
            return self.latest_tab(browser_id)

    def init_browser(self, browser_id=None):
        """
        初始化浏览器并清理缓存
        :param browser_id: 浏览器ID，用于多浏览器模式
        """
        co = ChromiumOptions().set_browser_path(self.chrome_path or self.edge_path)
        if self.multi_browser_mode:
            port = self._get_next_port()
            co.set_local_port(port)
            logger.debug(f"创建新浏览器实例，端口: {port}")
        else:
            co.set_local_port(9223)
        co.incognito(True)
        
        if self.multi_browser_mode:
            browser = Chromium(co)
            browser.clear_cache()
            browser.cookies().clear()
            self._browsers[browser_id] = browser
        else:
            self.browser = Chromium(co)
            self.browser.clear_cache()
            self.browser.cookies().clear()

    def auto_login_with_cookies(self, url, cookies_name):
        """
        模拟登录，访问登录页面
        """
        tab = self.latest_tab()
        tab.set.cookies.clear()
        tab.get(url)

        # 持续监听浏览器Cookies, 判断cookies_name是否存在
        while True:
            cookies = tab.cookies().as_dict()
            if cookies_name in cookies and cookies.get(cookies_name):
                logger.info(f"Cookies {cookies_name} 已存在")
                break
            logger.debug(cookies)
            time.sleep(0.1)
        logger.info(f"登录成功: {cookies}")
        tab.close()
        return cookies

    def login(self):
        """
        人工登陆账号
        :return:
        """
        ...

    def listen_network_requests(self, tab, success_indicator="loginSuccess"):
        """
        监听网络请求，判断是否登录成功
        :param tab: 当前浏览器标签
        :param success_indicator: 成功登录的标志（可以根据URL或响应数据来定义）
        :return: 是否成功
        """

        def on_request(request):
            logger.debug(f"Network Request: {request.url}")
            if success_indicator in request.url:
                logger.info("登录成功")
                return True
            return False

        tab.on('network.response', on_request)
        return False  # 默认未成功，具体实现取决于判断逻辑

    def inject_js(self, tab, js_code):
        """
        在浏览器中注入 JS
        :param tab: 当前浏览器标签
        :param js_code: 需要注入的 JS 代码
        """
        tab.run_js(js_code)

    def set_cookies(self, tab, cookies, domain):
        """
        设置 cookies
        :param domain:
        :param tab: 当前浏览器标签
        :param cookies: 需要设置的 cookies 字典
        """
        logger.debug(f"设置Cookies: {cookies}, domain: {domain}")
        # 先清空
        tab.set.cookies.clear()

        cookies_str = '; '.join([f"{k}={v}" for k, v in cookies.items()])

        if isinstance(domain, str):
            cookies_str += f"; domain={domain}"
            tab.set.cookies(cookies_str)
        elif isinstance(domain, list):
            for _domain in domain:
                cookies_str += f"; domain={_domain}"
                tab.set.cookies(cookies_str)
        else:
            logger.error("未知的 domain 类型")
            return False

        return True

    def close_browser(self, browser_id=None):
        """
        关闭浏览器
        :param browser_id: 浏览器ID，用于多浏览器模式
        """
        if self.multi_browser_mode and browser_id in self._browsers:
            try:
                self._browsers[browser_id].quit()
                del self._browsers[browser_id]
                logger.debug(f"关闭浏览器: {browser_id}")
            except Exception as e:
                logger.error(f"关闭浏览器失败: {e}")
        elif not self.multi_browser_mode and self.browser:
            try:
                self.browser.quit()
                self.browser = None
                logger.debug("关闭浏览器")
            except Exception as e:
                logger.error(f"关闭浏览器失败: {e}")

    def __del__(self):
        """
        析构函数，确保所有浏览器实例都被关闭
        """
        if self.multi_browser_mode:
            for browser_id in list(self._browsers.keys()):
                self.close_browser(browser_id)
        else:
            self.close_browser()


def test():
    browser = Browser(multi_browser_mode=True)
    # 测试多浏览器模式
    for i in range(3):
        browser_id = f"browser_{i}"
        tab = browser.latest_tab(browser_id)
        cookies = {
            "gd_random": "eyJtYXRjaCI6dHJ1ZSwicGVyY2VudCI6MC40MjQyOTk4MjE0OTAyMzcwNH0=.9zgJo+BhWliDs/KsErDeSOXQ4rcc6gqhHYssKohwM98=",
            "biz_trace_id": "603b42a3",
            "passport_csrf_token": "1dbc4f8d74bfd5f325d6b11be08dea6d",
            "passport_csrf_token_default": "1dbc4f8d74bfd5f325d6b11be08dea6d",
            "n_mh": "XKutLHrFWXxvtsRAOgO42oBvB_2oj9w7eU134_3lnFI",
            "passport_auth_status": "bfd2eb8011ba9504cc4b58ed47e0c6cb%2C",
            "passport_auth_status_ss": "bfd2eb8011ba9504cc4b58ed47e0c6cb%2C",
            "sid_guard": "86487e2d4f37aa75203af1eec390cd64%7C1754043393%7C5184000%7CTue%2C+30-Sep-2025+10%3A16%3A33+GMT",
            "uid_tt": "e79b26ffd0ba50011698f2214fde26c4",
            "uid_tt_ss": "e79b26ffd0ba50011698f2214fde26c4",
            "sid_tt": "86487e2d4f37aa75203af1eec390cd64",
            "sessionid": "86487e2d4f37aa75203af1eec390cd64",
            "sessionid_ss": "86487e2d4f37aa75203af1eec390cd64",
            "session_tlb_tag": "sttt%7C13%7Chkh-LU83qnUgOvHuw5DNZP_________GuBGDPSnEJEGIeQ6siFdcCS6sqSCRFE5NuwjIPLe0KZ8%3D",
            "is_staff_user": "false",
            "sid_ucp_v1": "1.0.0-KGZiNmUwNWIwYmU1MWFkNTFjYTg0YmEzZmIwZTNlZWViOTdjZDViZTcKFwjHoZD-qoyTAhCBqLLEBhibFjgCQPEHGgJsZiIgODY0ODdlMmQ0ZjM3YWE3NTIwM2FmMWVlYzM5MGNkNjQ",
            "ssid_ucp_v1": "1.0.0-KGZiNmUwNWIwYmU1MWFkNTFjYTg0YmEzZmIwZTNlZWViOTdjZDViZTcKFwjHoZD-qoyTAhCBqLLEBhibFjgCQPEHGgJsZiIgODY0ODdlMmQ0ZjM3YWE3NTIwM2FmMWVlYzM5MGNkNjQ"
}
        _set_result = browser.set_cookies(tab, cookies, '.toutiao.com')
        if not _set_result:
            logger.warning(f"设置Cookies失败: {browser_id}")
            continue

        tab.get('https://novelcp.toutiao.com/page/datacenter/bookverify')
        time.sleep(2)  # 等待页面加载
        break

    input("按任意键退出...")  # 保持浏览器窗口打开


if __name__ == '__main__':
    test()


